home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
IRIX 6.2 Applications 1996 May
/
SGI IRIX 6.2 Applications 1996 May.iso
/
dist
/
impr_dev.idb
/
usr
/
impressario
/
src
/
libimp
/
impClose.c.z
/
impClose.c
Wrap
C/C++ Source or Header
|
1996-05-06
|
9KB
|
348 lines
/**************************************************************************
*
* Copyright (c) 1993 Silicon Graphics, Inc.
* All Rights Reserved
*
* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF SGI
*
* The copyright notice above does not evidence any actual of intended
* publication of such source code, and is an unpublished work by Silicon
* Graphics, Inc. This material contains CONFIDENTIAL INFORMATION that is
* the property of Silicon Graphics, Inc. Any use, duplication or
* disclosure not specifically authorized by Silicon Graphics is strictly
* prohibited.
*
* RESTRICTED RIGHTS LEGEND:
*
* Use, duplication or disclosure by the Government is subject to
* restrictions as set forth in subdivision (c)(1)(ii) of the Rights in
* Technical Data and Computer Software clause at DFARS 52.227-7013,
* and/or in similar or successor clauses in the FAR, DOD or NASA FAR
* Supplement. Unpublished - rights reserved under the Copyright Laws of
* the United States. Contractor is SILICON GRAPHICS, INC., 2011 N.
* Shoreline Blvd., Mountain View, CA 94039-7311
**************************************************************************
*
* File: impClose.c
*
* Description: Routines to close an open SGI Image file.
*
**************************************************************************/
#ident "$Revision: 1.7 $"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include "impI.h"
/* Local functions */
static int closeImage(IMPImage *image, int *fdp);
static int flushImage(IMPImage *image);
/**************************************************************************
*
* Function: impClose
*
* Description: Closes an SGI Image file previsouly opened by a call to
* impOpen or impOpenFd. Note that the file descriptor for the image
* is also closed.
*
* Parameters:
* image (I) - image to close
*
* Return: 0 if sucessful. -1 is returned and IMPerrno is set if an error
* has occurred.
*
**************************************************************************/
int impClose(IMPImage *image)
{
int fd;
/*
* Close the image. The image structure is deallocated
* and invalid from this point on.
*/
if (closeImage(image, &fd) < 0)
_impReturnError(IMPerrno);
/*
* Close the image file descriptor
*/
if (fd != -1) {
if (close(fd) < 0)
_impReturnError(errno);
}
return 0;
}
/**************************************************************************
*
* Function: impCloseFd
*
* Description: Closes an SGI Image file previsouly opened by a call to
* impOpen or impOpenFd. Note that the file descriptor for the image
* is left open.
*
* Parameters:
* image (I) - image to close
* fdp (O) - image file descriptor, left open after call
*
* Return: 0 if sucessful. -1 is returned and IMPerrno is set if an error
* has occurred.
*
**************************************************************************/
int impCloseFd(IMPImage *image, int *fdp)
{
/*
* Close the image. The image structure is deallocated
* and invalid from this point on.
*/
if (closeImage(image, fdp) < 0)
_impReturnError(IMPerrno);
return 0;
}
/*
============================================================================
LOCAL FUNCTIONS
============================================================================
*/
/**************************************************************************
*
* Function: closeImage
*
* Description: Closes an SGI Image file previsouly opened by a call to
* impOpen but does not close the file descriptor associated with
* the image.
*
* Parameters:
* image (I) - image to close
* fdp (O) - image file descriptor
*
* Return: 0 if sucessful. -1 is returned and IMPerrno is set if an error
* has occurred.
*
**************************************************************************/
int closeImage(IMPImage *image, int *fdp)
{
/*
* Sanity check the inputs
*/
assert(image != NULL);
assert(fdp != NULL);
/*
* Send back the image file descriptor
*/
*fdp = image->file;
/*
* Flush any pending writes
*/
if (flushImage(image) < 0)
_impReturnError(IMPerrno);
/*
* If we are writing the image, write out the current header;
* if RLE, write the RLE tables; if the image has extension tags, write
* them as well.
*/
if (_impWriting(image)) {
int retv;
struct stat buf;
off_t length, begin;
if(impHasTags(image) ) {
/* Pretty stupid, but I don't think there's any other way to find
* the length of this file */
fstat(image->file, &buf);
length = buf.st_size;
begin = (length + 3) & ~0x3;
} else {
begin = 0;
}
if (image->dorev)
_impSwapLongs((__uint32_t *) &begin, sizeof(long));
/*
* Seek to start of file
*/
if (_impSeekOffset(image, image->start) < 0)
_impReturnError(IMPerrno);
/*
* Update the image header on disk, byte swapping
* if necessary. If we swap we un-swap after the write.
*/
if (image->dorev)
_impSwapHeader(image);
retv = _impWrite(image, image, sizeof(IMPImage));
if (image->dorev)
_impSwapHeader(image);
if (retv != sizeof(IMPImage))
_impReturnError(IMPerrno);
/* Write the pointer to the start of the extension tags, or 0 if
* there are no extension tags */
if (_impSeekOffset(image, IMP_TAG_PTR_OFFSET) < 0)
_impReturnError(IMPerrno);
retv = _impWrite(image, &begin, sizeof(long));
if (image->dorev)
_impSwapLongs((__uint32_t *) &begin, sizeof(long));
if (retv != sizeof(long))
_impReturnError(IMPerrno);
/*
* Write the RLE tables if this is an RLE image
*/
if (impIsRLE(image)) {
int rleTableSize;
if (_impSeekOffset(image, image->start + _IMP_TABLES_START) < 0)
_impReturnError(IMPerrno);
rleTableSize = impYSize(image) * impNumChannels(image) *
sizeof(__int32_t);
if (image->dorev) {
_impSwapLongs(image->rowstart, rleTableSize);
_impSwapLongs((__uint32_t*)image->rowsize, rleTableSize);
}
if (_impWrite(image, image->rowstart, rleTableSize) != rleTableSize)
_impReturnError(IMPerrno);
if (_impWrite(image, image->rowsize, rleTableSize) != rleTableSize)
_impReturnError(IMPerrno);
}
/*
* Write extension tags, if any
*/
if (impHasTags(image)) {
char pad[4], *magic = "tags";
IMPTag *pTag, *next, dummyTag;
/* Just double-checking */
fstat(image->file, &buf);
#if 0
assert(length == buf.st_size);
/* Seek to the end of the file */
if (_impSeekOffset(image, length) < 0)
_impReturnError(IMPerrno);
#else
/* Seek to the end of the file */
if (_impSeekOffset(image, buf.st_size) < 0)
_impReturnError(IMPerrno);
#endif
if(begin - length > 0) { /* pad to start on word boundary */
if(_impWrite(image, &pad, begin - length) != begin - length)
_impReturnError(IMPerrno);
}
/* Write the extension tag delimiter */
dummyTag.header.tagname = IMP_TAG_FIRST_TAG;
dummyTag.header.length = 4;
if (_impWrite(image, &dummyTag.header, sizeof(IMPTagHeader)) !=
sizeof(IMPTagHeader))
_impReturnError(IMPerrno);
if (_impWrite(image, magic, strlen(magic)) != strlen(magic))
_impReturnError(IMPerrno);
/* write each tag */
pTag = impTags(image);
while (pTag) {
__uint32_t lenTag;
lenTag = pTag->header.length;
if (_impWrite(image, pTag, sizeof(IMPTagHeader)) !=
sizeof(IMPTagHeader))
_impReturnError(IMPerrno);
if (_impWrite(image, pTag->data, lenTag) != lenTag)
_impReturnError(IMPerrno);
next = pTag->next;
free(pTag->data);
free(pTag);
pTag = next;
}
/* Write the last tag */
dummyTag.header.tagname = IMP_TAG_LAST_TAG;
dummyTag.header.length = 0;
if (_impWrite(image, &dummyTag, sizeof(IMPTagHeader)) !=
sizeof(IMPTagHeader))
_impReturnError(IMPerrno);
}
}
/*
* Free any allocated buffer storage
*/
if (image->base)
free(image->base);
if (image->tmpbuf)
free(image->tmpbuf);
if (impIsRLE(image)) {
free(image->rowstart);
free(image->rowsize);
}
if (_impReading(image)) {
if (image->cache == IMPHeapCache && image->cachebuf)
free(image->cachebuf);
if (image->cache == IMPMapCache && image->cachebuf)
munmap(image->cachebuf, image->cachesize);
}
/*
* Blow away the image structure
*/
free(image);
return 0;
}
/**************************************************************************
*
* Function: flushImage
*
* Description: Flushes any pending writes to an image file.
*
* Parameters:
* image (I) - image file
*
* Return: 0 if successful. -1 and IMPerrno set if errors.
*
**************************************************************************/
static int flushImage(IMPImage *image)
{
if (_impWriting(image)) {
short *base;
if ((base = image->base) != NULL && (image->ptr - base) > 0) {
if (impWriteRow(image, base, image->y, image->z) != impXSize(image))
_impReturnError(IMPerrno);
}
}
return 0;
}